﻿using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace LightGameLibs.Editor
{
    public class LocalizeConfigWindow : EditorWindow
    {
        private List<string> m_tagsString = new List<string>();
        private List<LocalizeElement> m_localizeElements = new List<LocalizeElement>();
        private List<int> m_searched = new List<int>();
        private const string c_enumScriptPathKey = "LOCAL_LOCALIZATION_SCRIPT_PATH";
        private const string c_tablePathStoreKey = "LOCAL_LOCALIZATION_TABLE_PATH";
        private string m_scriptPath;
        private string m_tablePath;
        private string m_addEnumName = string.Empty;
        private string m_addText = string.Empty;
        private string m_searchString = string.Empty;
        private bool m_notFound;
        private Vector2 m_scrollPos;
        private bool m_check;

        [MenuItem("LightGameLibs/Configs/LocalizeConfig")]
        private static void ShowWindow()
        {
            GetWindow<LocalizeConfigWindow>(true, "LocalizeConfigWindow").Show();
        }

        void Awake()
        {
            m_check = true;

            if (string.IsNullOrEmpty(EditorPrefs.GetString(c_enumScriptPathKey, string.Empty)))
            {
                m_scriptPath = Application.dataPath.Add("/Plugins/LightGameLibs/Localization/GeneratedScripts/LocalizationTag.cs");
                EditorPrefs.SetString(c_enumScriptPathKey, m_scriptPath);
            }

            m_scriptPath = EditorPrefs.GetString(c_enumScriptPathKey, m_scriptPath);

            if (!System.IO.File.Exists(m_scriptPath))
            {
                DebugMgr.LogError(DebugTag.LOCALDATABASE, "Cant find script");
                m_check = false;
            }

            if (string.IsNullOrEmpty(EditorPrefs.GetString(c_tablePathStoreKey, string.Empty)))
            {
                m_tablePath = Application.dataPath.Add("/Plugins/LightGameLibs/Localization/Tables/Localization.json");
                EditorPrefs.SetString(c_tablePathStoreKey, m_tablePath);
            }

            m_tablePath = EditorPrefs.GetString(c_tablePathStoreKey, m_tablePath);

            if (!System.IO.File.Exists(m_tablePath))
            {
                DebugMgr.LogError(DebugTag.LOCALDATABASE, "Cant find table");
                m_check = false;
            }

            ReadTable();
        }

        void OnGUI()
        {
            EditorGUILayout.BeginVertical();
            EditorGUILayout.LabelField("File Address:");
            if (EditorUtil.BrowsableAddress("Script", m_scriptPath, c_enumScriptPathKey, "cs"))
            {
                m_check = true;
                m_scriptPath = EditorPrefs.GetString(c_enumScriptPathKey);
            }
            if (EditorUtil.BrowsableAddress("Table", m_tablePath, c_tablePathStoreKey, "json"))
            {
                m_check = true;
                m_tablePath = EditorPrefs.GetString(c_tablePathStoreKey);
            }
            EditorGUILayout.EndVertical();

            if (!m_check)
            {
                return;
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Search:");
            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            m_searchString = EditorGUILayout.TextField(m_searchString);
            if (GUILayout.Button("Search"))
            {
                Search();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Content:");

            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Tag Name");
            EditorGUILayout.LabelField("Text");
            EditorGUILayout.EndHorizontal();

            m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos);
            for (int i = 0, length = m_tagsString.Count; i < length; i++)
            {
                if ((m_searched.Count > 0 && !m_searched.Contains(i)) || m_notFound)
                {
                    continue;
                }

                EditorGUILayout.BeginHorizontal();
                m_tagsString[i] = EditorGUILayout.TextField(m_tagsString[i]);
                m_localizeElements[i].text = EditorGUILayout.TextField(m_localizeElements[i].text);
                if (GUILayout.Button("Delete"))
                {
                    DeleteEnum(i);
                    return;
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Apply Setting"))
            {
                ConfigApply();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Add:");

            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            m_addEnumName = EditorGUILayout.TextField("Enum Tag Name:", m_addEnumName).ToUpper();
            m_addText = EditorGUILayout.TextField(m_addText);
            EditorGUILayout.EndHorizontal();
            if (GUILayout.Button("Add"))
            {
                AddEnum();
            }
            EditorGUILayout.EndVertical();
        }

        private void ReadTable()
        {
            m_tagsString.Clear();
            m_localizeElements.Clear();
            var table = LocalDatabase.GetDatabase<LocalizeElement>(DBTag.LOCALIZATION);

            foreach (var item in table)
            {
                m_tagsString.Add(((LocalizationTag)item.Key).ToString());
                m_localizeElements.Add((LocalizeElement)item.Value);
            }
        }

        private void Search()
        {
            m_searched.Clear();
            m_notFound = true;
            if (m_tagsString.Count <= 0 || string.IsNullOrEmpty(m_searchString))
            {
                m_notFound = false;
                return;
            }

            for (int i = 0, length = m_tagsString.Count; i < length; i++)
            {
                if (m_tagsString[i].ToLower().Contains(m_searchString.ToLower())
                     || m_localizeElements[i].text.ToLower().Contains(m_searchString.ToLower()))
                {
                    m_notFound = false;
                    m_searched.Add(i);
                }
            }
        }

        private void ConfigApply()
        {
            EditorUtil.WriteEnumToCS("LocalizationTag", m_tagsString.ToArray(),
                 string.Empty, -1, m_scriptPath, string.Empty, "LightGameLibs", true);
            EditorUtil.WriteArrayToJson(m_localizeElements.ToArray(), m_tablePath);
        }

        private void AddEnum()
        {
            if (string.IsNullOrEmpty(m_addEnumName))
            {
                DebugMgr.Log(DebugTag.LOCALDATABASE, "Please enter name");
                return;
            }

            if (m_tagsString.Contains(m_addEnumName))
            {
                DebugMgr.LogError(DebugTag.LOCALDATABASE, "Enum already exist");
                return;
            }

            int enumNum = EditorUtil.WriteEnumToCS("LocalizationTag", m_tagsString.ToArray(),
                 string.Empty, -1, m_scriptPath, m_addEnumName, "LightGameLibs", true);

            m_tagsString.Add(m_addEnumName);

            var element = new LocalizeElement();
            element.ID = enumNum;
            element.text = m_addText;
            m_localizeElements.Add(element);

            EditorUtil.WriteArrayToJson(m_localizeElements.ToArray(), m_tablePath);
        }

        private void DeleteEnum(int target)
        {
            m_tagsString.RemoveAt(target);
            m_localizeElements.RemoveAt(target);
            for (int i = 0, length = m_localizeElements.Count; i < length; i++)
            {
                if (i >= target)
                {
                    m_localizeElements[i].ID--;
                }
            }
            EditorUtil.WriteEnumToCS("LocalizationTag", m_tagsString.ToArray(),
                string.Empty, -1, m_scriptPath, string.Empty, "LightGameLibs", true);
            EditorUtil.WriteArrayToJson(m_localizeElements.ToArray(), m_tablePath);
        }
    }
}
